from django.shortcuts import render
from django.shortcuts import redirect
from django.shortcuts import reverse
from django.shortcuts import HttpResponse
from django import views
from django.db import DatabaseError
from rbac.forms.permission import MultiPermissionsForm
from django.forms import formset_factory
from rbac import models
from collections import OrderedDict
from rbac.service.routes import get_all_url_dict
from rbac.forms.permission import PermissionModelForm
from django.conf import settings
from django.utils.module_loading import import_string

class PermissionListView(views.View):
    '''
    查看权限
    '''
    def get(self,request):
        permission_list=models.Permission.objects.all()
        return render(request,'rbac/permission_list.html',{'data_list':permission_list})


class PermissionAddView(views.View):
    '''
    权限添加
    '''
    def get(self,request):
        form=PermissionModelForm()
        return render(request,'rbac/permission_change.html',{'form':form})
    def post(self,request):
        form=PermissionModelForm(data=request.POST)
        if form.is_valid():
            form.save()
            return redirect(reverse('rbac:permission_list'))
        else:
            return render(request,'rbac/permission_change.html',{'form':form})


class PermissionEditView(views.View):
    '''
    权限编辑
    '''
    def get(self,request):
        return render(request,'')

class PermissionDeleteView(views.View):
    '''
    权限删除
    '''
    def get(self,request):
        return render(request,'')


class MultiPermissionsView(views.View):
    '''
    权限批量操作
    '''
    def get(self,request,):
        post_type=request.GET.get('post_type')
        #生成多个formset类
        MultiPermissionsFormSet=formset_factory(MultiPermissionsForm,extra=0)
        generate_formset=None
        update_formset=None
        delete_formset=None
        #数据库中获取权限
        permission_set=models.Permission.objects.values('id','title','url','name','menu_id','parent_id')
        #生成有序字典对象
        permission_orderdict=OrderedDict()
        for item in permission_set:
            permission_orderdict[item['name']]=item
        #permission_name_set
        #数据库中所有的权限name 的set
        permission_name_set=set(permission_orderdict.keys())
        #获取路由系统 中的url
        router_dict=get_all_url_dict(ignore_namespace_list=['admin',])
        for item in permission_set:
            name=item['name']
            if name in router_dict:
                router_dict[name].update(item)
        #路由系统中所有权限name的集合
        router_name_set=set(router_dict.keys())
        #需要新建  数据库无 路由有
        if not generate_formset:
            generate_name_list=router_name_set-permission_name_set
            generate_formset=MultiPermissionsFormSet(initial=[row for name,row in router_dict.items() if name in generate_name_list])

        #需要删除   数据库有 路由没有
        if not delete_formset:
            delete_name_list=permission_name_set-router_name_set
            delete_formset=MultiPermissionsFormSet(initial=[row for name,row in router_dict.items() if name in delete_name_list])
        #需要更新  数据库有  路由有
        if not update_formset:
            update_name_list=permission_name_set.intersection(router_name_set)
            update_formset=MultiPermissionsFormSet(initial=[row for name,row in router_dict.items() if name in update_name_list])
        return render(request,'rbac/multi_permissions.html',{
            'destroy_formset': delete_formset,
            'update_formset': update_formset,
            'generate_formset': generate_formset,
        })

    def post(self,request):
        post_type = request.GET.get('type')
        MultiPermissionFormSet = formset_factory(MultiPermissionsForm, extra=0)
        generate_formset = None
        update_formset = None
        delete_formset=None
        if post_type=='generate':
            #新建权限的操作
            formset=MultiPermissionFormSet(request.POST)
            if not formset.is_valid():
                generate_formset=formset
            else:
                #在数据库中添加数据
                for row_dict in formset.cleaned_data:
                    row_dict.pop('id')
                    models.Permission.objects.create(**row_dict)
        if post_type=='update':
            formset=MultiPermissionFormSet(request.POST)
            if formset.is_valid():
                for row_dict in formset.cleaned_data:
                    permission_id=row_dict.pop('id')
                    models.Permission.objects.filter(pk=permission_id).update(**row_dict)
            else:
                update_formset=formset

        return render(request, 'rbac/multi_permissions.html', {
            'destroy_formset': delete_formset,
            'update_formset': update_formset,
            'generate_formset': generate_formset,
        })


class PermissionDisTribute(views.View):

    def get(self,request):

        uid = request.GET.get('uid')
        rid = request.GET.get('rid')
        user_class = import_string(settings.USER_MODEL_PATH)
        #用户信息
        user_list=user_class.objects.all()  #用户列表
        #角色信息
        user_has_roles=user_class.objects.filter(pk=uid).values('id','roles')
        user_has_roles_dict={item['roles']:None for item in user_has_roles}  #{1: None, 5: None}
        #所有角色
        role_list=models.Role.objects.all()    #权限列表
        #权限信息
        all_menu_list=[]
        role_has_permission=[]
        if rid:
            role_has_permission=models.Role.objects.filter(pk=rid,permissions__isnull=False).values('id','permissions')
        elif uid and not rid:
            user = user_class.objects.filter(pk=uid).first()
            if not user:
                return HttpResponse('该用户不存在')
            else:
                role_has_permission = user.roles.filter(permissions__isnull=False).values('id', 'permissions')
        else:
            role_has_permission=[]
        role_has_permission_dict={item['permissions']:None for item in  role_has_permission}
        #菜单
        queryset=models.Menu.objects.values('id','title')
        menu_dict={}
        for item in queryset:
            item['children']=[]
            menu_dict[item['id']]=item
            all_menu_list.append(item)
        other={'id':None,'title':'其他','children':[]}
        all_menu_list.append(other)  #  [{'id': 1, 'title': '菜单一', 'children': []}, {'id': 3, 'title': '菜单三', 'children': []}, {'id': 2, 'title': '菜单二', 'children': []}, {'id': None, 'title': '其他', 'children': []}】
        menu_dict[None]=other

        #根权限
        root_permission=models.Permission.objects.filter(menu__isnull=False).values('id','title','menu_id')
        root_permission_dict={}  #父权限 字典
        for per in root_permission:
            per['children']=[]
            nid=per['id']
            menu_id=per['menu_id']
            root_permission_dict[nid]=per
            menu_dict[menu_id]['children'].append(per)

        #子权限
        node_permission=models.Permission.objects.filter(menu__isnull=True).values('id','title','parent_id')
        for per in node_permission:
            parent_id=per['parent_id']
            if not parent_id:
                menu_dict[None]['children'].append(per)
                continue
            root_permission_dict[parent_id]['children'].append(per)

        return render(request,'rbac/distribute_permission.html',{
            'user_list': user_list,
            'role_list': role_list,
            'user_has_roles_dict': user_has_roles_dict,
            'role_has_permissions_dict': role_has_permission_dict,
            'all_menu_list': all_menu_list,
            'uid': uid,
            'rid': rid
        })

    def post(self,request):

        '''
        处理权限分配操作
        :param request:
        :return:
        '''
        uid = request.GET.get('uid')
        rid = request.GET.get('rid')
        user_class = import_string(settings.USER_MODEL_PATH)
        if request.POST.get('postType') == 'role':
            user=user_class.objects.filter(pk=uid).first()
            if not user:
                return HttpResponse('用户不存在')
            else:
                user.roles.set(request.POST.getlist('roles'))
                params_temp = request.GET.copy()
                params=params_temp.urlencode()

                return redirect(reverse('rbac:permission_add'))

        if request.POST.get('postType')=='permission' and rid:
            role=models.Role.objects.filter(pk=rid).first()
            if not role:
                return HttpResponse('角色不存在')
            else:
                role.permissions.set(request.POST.getlist('permissions'))
                return redirect(reverse('rbac:permission_add'))